package com.wy.allthingdone.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.graphics.Path;
import android.view.View;

/**
 * Created by 38270 on 2016/11/18.
 * 自定义条形图
 */

public class BarChart extends View {
    private Paint mPaint;
    private int mwidth;
    private int mheight;
    private Paint linePaint;
    private Path linePath;

    public BarChart(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {//
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(3);
        mPaint.setStyle(Paint.Style.FILL);

        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        linePaint.setStyle(Paint.Style.STROKE);
        linePaint.setColor(Color.CYAN);
        linePaint.setStrokeWidth(2);
        // 实例化路径
        linePath = new Path();
    }

    public BarChart(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public BarChart(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BarChart(Context context) {
        super(context);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        init();
        drawXYhistonal(canvas);
        drawXYvalue(canvas);
        drawWaveView(canvas);
    }

    private void drawWaveView(Canvas canvas) {
        /*
         * 设置Path起点
         * 注意我将Path的起点设置在了控件的外部看不到的区域
         * 如果我们将起点设置在控件左端x=0的位置会使得贝塞尔曲线变得生硬
         * 至于为什么刚才我已经说了
         * 所以我们稍微让起点往“外”走点
         */
        linePath.moveTo(-1 / 4F * vWidth, waveY);

        /*
         * 以二阶曲线的方式通过控制点连接位于控件右边的终点
         * 终点的位置也是在控件外部
         * 我们只需不断让ctrX的大小变化即可实现“浪”的效果
         */
        linePath.quadTo(ctrX, ctrY, vWidth + 1 / 4F * vWidth, waveY);
//        linePath.cubicTo(ctrX, ctrY, ctrX + 200, ctrY - 100, vWidth + 1 / 4F * vWidth, waveY);

        // 围绕控件闭合曲线
        linePath.lineTo(vWidth + 1 / 4F * vWidth, vHeight);
        linePath.lineTo(-1 / 4F * vWidth, vHeight);
        linePath.close();

        canvas.drawPath(linePath, linePaint);

        /*
         * 当控制点的x坐标大于或等于终点x坐标时更改标识值
         */
        if (ctrX >= vWidth + 1 / 4F * vWidth) {
            isInc = false;
        }
        /*
         * 当控制点的x坐标小于或等于起点x坐标时更改标识值
         */
        else if (ctrX <= -1 / 4F * vWidth) {
            isInc = true;
        }

        // 根据标识值判断当前的控制点x坐标是该加还是减
        ctrX = isInc ? ctrX + 20 : ctrX - 20;

        /*
         * 让“水”不断减少
         */
        if (ctrY <= vHeight) {
            ctrY += 2;
            waveY += 2;
        }

        linePath.reset();

        // 重绘
        invalidate();
    }

    private void drawXYvalue(Canvas canvas) {
        // 移动点至[100,100]
        linePath.moveTo(100, 100);
        // 一介贝塞尔曲线 200，200为控制点
        linePath.quadTo(200, 200, 400, 100);

        linePath.moveTo(100, 100);
        //二介贝塞尔曲线 200，200 ，300 ，0 为控制点
        linePath.cubicTo(200, 200, 300, 0, 400, 100);
        canvas.drawPath(linePath, linePaint);
    }

    private void drawXYhistonal(Canvas canvas) {
        canvas.drawLine(getPaddingLeft(), mheight - getPaddingBottom(),
                mwidth - getPaddingRight(), mheight - getPaddingBottom(),
                mPaint);//两点之间的线
        canvas.drawCircle(getPaddingLeft(), mheight - getPaddingBottom(), 5, mPaint);//画圆点
        canvas.drawLine(mwidth - getPaddingRight(), mheight - getPaddingBottom(), mwidth - getPaddingRight() - 20, mheight - getPaddingBottom() - 10, mPaint);
        canvas.drawLine(mwidth - getPaddingRight(), mheight - getPaddingBottom(), mwidth - getPaddingRight() - 20, mheight - getPaddingBottom() + 10, mPaint);
        canvas.drawLine(getPaddingLeft(), mheight - getPaddingBottom(), getPaddingLeft(), getPaddingBottom(), mPaint);
        canvas.drawLine(getPaddingLeft(), getPaddingBottom(), getPaddingRight() - 10, getPaddingBottom() + 20, mPaint);
        canvas.drawLine(getPaddingLeft(), getPaddingBottom(), getPaddingRight() + 10, getPaddingBottom() + 20, mPaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        Log.d("MyView", "---widthSpecSize = " + widthSpecSize + "");
        Log.d("MyView", "---heightSpecSize = " + heightSpecSize + "");
        if (widthSpecSize == MeasureSpec.AT_MOST) {//wrapcontent
            Log.d("MyView", "---AT_MOST---");
        }
        if (widthSpecSize == MeasureSpec.EXACTLY) {//自定义量 matchparent区别在于 size不一样
            mwidth = widthSpecSize;
        } else {
            mwidth = 300;
        }
        if (widthSpecSize == MeasureSpec.UNSPECIFIED) {
            Log.d("MyView", "---UNSPECIFIED---");
        }
        mwidth = widthSpecSize;
        mheight = heightSpecSize;
        setMeasuredDimension(mwidth, mheight);
    }

    private int vWidth, vHeight;// 控件宽高
    private float ctrX, ctrY;// 控制点的xy坐标
    private float waveY;// 整个Wave顶部两端点的Y坐标，该坐标与控制点的Y坐标增减幅一致

    private boolean isInc;// 判断控制点是该右移还是左移

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // 获取控件宽高
        vWidth = w;
        vHeight = h;

        // 计算控制点Y坐标
        waveY = 1 / 8F * vHeight;

        // 计算端点Y坐标
        ctrY = -1 / 16F * vHeight;
    }
}
